import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from skimage.io import imread, imshow
import cv2
from skfuzzy.cluster import cmeans
import itertools
import scipy
import warnings
warnings.filterwarnings('ignore')
image = imread('bacteries_1.jpg')
image1 = imread('bacteries_2.jpg')
imshow(image);
imshow(image1);
def convert_to_2d(image):
image_2d = image.reshape((-1,3))
image_2d = np.float32(image_2d)
return image_2d
image_2d = convert_to_2d(image)
image1_2d = convert_to_2d(image1)
MAX_ITER = 100
EPSILON = 0.85
CRITERIA = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, MAX_ITER, EPSILON)
ATTEMPTS = 10
CENTERS_METHODS = (cv2.KMEANS_PP_CENTERS, cv2.KMEANS_RANDOM_CENTERS)
CLUSTERS_RANGE = range(1, 11)
def calculate_intracluster_distance_sum(cluster_elements, centroid):
return sum([scipy.spatial.distance.sqeuclidean(centroid, element) for element in cluster_elements])
def get_intercluster_distance(centroid, centers):
# if len(centers) > 1:
# return scipy.spatial.distance.pdist(centers, 'sqeuclidean').min()
return sum([scipy.spatial.distance.sqeuclidean(centroid, centroid_other) for centroid_other in centers])
# else:
# return 0
def xie_benie(segmented_image, centers):
xb = sum([calculate_intracluster_distance_sum(segmented_image[segmented_image == center], center)
for center in centers]) / (
sum([get_intercluster_distance(centroid, centers) for centroid in centers])
* segmented_image.reshape((-1, 3)).shape[0])
return xb
def kmeans_segmentation(image2d, original_image_shape, n_clusters, criteria, attempts, centers_method):
retval, labels, centers = cv2.kmeans(image2d, n_clusters, None, criteria,
attempts, centers_method)
centers = np.uint8(centers)
segmented_data = centers[labels.flatten()]
segmented_image = segmented_data.reshape((original_image_shape))
return segmented_image, centers
def create_segmented_mapping(image2d, original_image_shape, centers_methods, nclusters_range):
mapping = {center: {n: None for n in nclusters_range} for center in centers_methods}
for center_method, nclusters in itertools.product(centers_methods, nclusters_range):
mapping[center_method][nclusters] = kmeans_segmentation(image2d, original_image_shape,
nclusters, criteria=CRITERIA,
attempts=ATTEMPTS,
centers_method=center_method)
return mapping
segmented_images_kmeans_mapping = create_segmented_mapping(image_2d, image.shape, CENTERS_METHODS, CLUSTERS_RANGE)
segmented_images1_kmeans_mapping = create_segmented_mapping(image1_2d, image1.shape, CENTERS_METHODS,
CLUSTERS_RANGE)
fig, axs = plt.subplots(nrows=10, ncols=2, figsize=(20, 50))
for i, nclusters in enumerate(CLUSTERS_RANGE):
for j, center_method in enumerate(CENTERS_METHODS):
axs[i][j].imshow(segmented_images_kmeans_mapping.get(center_method).get(nclusters)[0], aspect='auto');
axs[i][0].set_title('PP Centers, {} clusters'.format(nclusters))
axs[i][1].set_title('Random Centers, {} clusters'.format(nclusters))
fig, axs = plt.subplots(nrows=10, ncols=2, figsize=(20, 50))
for i, nclusters in enumerate(CLUSTERS_RANGE):
for j, center_method in enumerate(CENTERS_METHODS):
axs[i][j].imshow(segmented_images1_kmeans_mapping.get(center_method).get(nclusters)[0], aspect='auto');
axs[i][0].set_title('PP Centers, {} clusters'.format(nclusters))
axs[i][1].set_title('Random Centers, {} clusters'.format(nclusters))
xie_beni_values = [[xie_benie(*segmented_images_kmeans_mapping.get(center_method).get(nclusters))
for nclusters in CLUSTERS_RANGE] for center_method in CENTERS_METHODS]
fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 6))
center_methods_titles = ('PP Centers', 'Random Centers')
for i in range(2):
axs[i].plot(xie_beni_values[i])
axs[i].set_title('Xie-Beni index, {} cluster centers'.format(center_methods_titles[i]))
axs[i].set_xlabel('Number of cluster')
xie_beni_values_image1 = [[xie_benie(*segmented_images1_kmeans_mapping.get(center_method).get(nclusters))
for nclusters in CLUSTERS_RANGE] for center_method in CENTERS_METHODS]
fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 6))
center_methods_titles = ('PP Centers', 'Random Centers')
for i in range(2):
axs[i].plot(xie_beni_values_image1[i])
axs[i].set_title('Xie-Beni index, {} cluster centers'.format(center_methods_titles[i]))
axs[i].set_xlabel('Number of cluster')
def fuzzy_cmeans_segmentation(image2d, original_shape, n_clusters, power, eps, max_iter):
centers, fuzzy_matrix = cmeans(image2d.T, n_clusters, power, eps, max_iter, seed=42)[:2]
centers = np.uint8(centers)
segmented_image = centers[fuzzy_matrix.argmax(axis=0)]
segmented_image = segmented_image.reshape(original_shape)
return segmented_image, fuzzy_matrix, centers
M = 2
segmented_images_fuzzy = [fuzzy_cmeans_segmentation(image_2d, image.shape, nclusters, M, EPSILON, MAX_ITER)
for nclusters in CLUSTERS_RANGE]
fig, axs = plt.subplots(nrows=len(CLUSTERS_RANGE), ncols=1, figsize=(10, 50))
for i, nclusters in enumerate(CLUSTERS_RANGE):
axs[i].imshow(segmented_images_fuzzy[i][0], aspect='auto');
axs[i].set_title('Fuzzy C-Means, {} clusters'.format(nclusters))
segmented_images1_fuzzy = [fuzzy_cmeans_segmentation(image1_2d, image1.shape, nclusters, M, EPSILON, MAX_ITER)
for nclusters in CLUSTERS_RANGE]
fig, axs = plt.subplots(nrows=len(CLUSTERS_RANGE), ncols=1, figsize=(10, 50))
for i, nclusters in enumerate(CLUSTERS_RANGE):
axs[i].imshow(segmented_images1_fuzzy[i][0], aspect='auto');
axs[i].set_title('Fuzzy C-Means, {} clusters'.format(nclusters))
xie_beni_values_fuzzy_cmeans = [xie_benie(segmented_images_fuzzy[i][0], segmented_images_fuzzy[i][2])
for i, nclusters in enumerate(CLUSTERS_RANGE)]
plt.plot(xie_beni_values_fuzzy_cmeans)
plt.title('Xie-Beni index')
plt.xlabel('Number of cluster');
xie_beni_values_fuzzy_cmeans_image1 = [xie_benie(segmented_images1_fuzzy[i][0], segmented_images_fuzzy[i][2])
for i, nclusters in enumerate(CLUSTERS_RANGE)]
plt.plot(xie_beni_values_fuzzy_cmeans_image1)
plt.title('Xie-Beni index')
plt.xlabel('Number of cluster');